////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Microsoft Corporation.  All rights reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "tinyhal.h"
#include "..\..\..\..\DeviceCode\Targets\Native\FM3\DeviceCode\FM3.h"

#define LCD_BUS8

//#define INSERT_NOP
//#define INSERT_WAIT
//#define LCD_WAIT    10

#define LCD_ADDRESS	(*(volatile unsigned char*)0x62000000)
#define LCD_VALUE   (*(volatile unsigned char*)0x62020000)

#ifdef LCD_BUS8
#define LCD_RESET   FM3_GPIO->PDOR3_f.P5

void P8_Initialize(void)
{
    FM3_GPIO->PFR0 &= 0xFCFF;   // P08(LCD RS), P09(SD-CS) GPIO
    FM3_GPIO->DDR0  |= 0x0300;  // P08(LCD RS), P09(SD-CS) output
    //FM3_GPIO->PFR3 &= 0xFFCF;   // P34(A24:LCD WE), P35(A23:LCD RESET) GPIO
    //FM3_GPIO->DDR3  |= 0x0030;  // P34(A24:LCD WE), P35(A23:LCD RESET) output
    FM3_GPIO->PFR3 &= 0xFFDF;   // P35(A23:LCD RESET) GPIO
    FM3_GPIO->DDR3  |= 0x0020;  // P35(A23:LCD RESET) output
    FM3_GPIO->PDOR0_f.P8 = 1;
    //FM3_GPIO->PDOR3_f.P4 = 1;
    FM3_GPIO->PDOR3_f.P5 = 1;
}

void LCD_nRESET(int n)
{
    if (n)
        LCD_RESET = 1;
    else
        LCD_RESET = 0;
}

void P8_LCD_index(volatile unsigned short index)
{
    FM3_GPIO->PDOR0_f.P8 = 0;   // RS 0
    LCD_ADDRESS = (unsigned char)(index >> 8);
    LCD_ADDRESS = (unsigned char)(index >> 0);
    return;
}

void P8_LCD_dat(volatile unsigned short data)
{
    FM3_GPIO->PDOR0_f.P8 = 1;   // RS 1
    LCD_VALUE = (unsigned char)(data >> 8);
    LCD_VALUE = (unsigned char)(data >> 0);
    return;
}

void P8_LCD_cmd(volatile unsigned short index, volatile unsigned short data)
{
    P8_LCD_index(index);
    P8_LCD_dat(data);
    return;
}

unsigned short P8_LCD_read_dat(volatile unsigned short index)
{
    volatile unsigned short data;
    P8_LCD_index(index);
    FM3_GPIO->PDOR0_f.P8 = 1;   // RS 1
    data = (unsigned short)LCD_VALUE;
    data = (data << 8) + (unsigned short)LCD_VALUE;
    return data;
}
#else
#define DDR_REST    PORT9.DDR.BIT.B3
#define DR_REST     PORT9.DR.BIT.B3
#define LCD_RESET   DR_REST

void P16_Initialize(void)
{
    FM3_GPIO->PFR0 &= 0xFCFF;   // P08(LCD RS), P09(SD-CS) GPIO
    FM3_GPIO->DDR0  |= 0x0300;  // P08(LCD RS), P09(SD-CS) output
    //FM3_GPIO->PFR3 &= 0xFFCF;   // P34(A24:LCD WE), P35(A23:LCD RESET) GPIO
    //FM3_GPIO->DDR3  |= 0x0030;  // P34(A24:LCD WE), P35(A23:LCD RESET) output
    FM3_GPIO->PFR3 &= 0xFFDF;   // P35(A23:LCD RESET) GPIO
    FM3_GPIO->DDR3  |= 0x0020;  // P35(A23:LCD RESET) output
    FM3_GPIO->PDOR0_f.P8 = 1;
    //FM3_GPIO->PDOR3_f.P4 = 1;
    FM3_GPIO->PDOR3_f.P5 = 1;
}

void LCD_nRESET(int n)
{
    if (n)
        LCD_RESET = 1;
    else
        LCD_RESET = 0;
}

void P16_LCD_cmd(volatile unsigned short index, volatile unsigned short data)
{
    LCD_ADDRESS = index;
    LCD_VALUE = data;
    return;
}

void P16_LCD_index(volatile unsigned short index)
{
    FM3_GPIO->PDOR0_f.P8 = 0;   // RS 0
    LCD_ADDRESS = index;
    return;
}

void P16_LCD_dat(volatile unsigned short data)
{
    FM3_GPIO->PDOR0_f.P8 = 1;   // RS 1
    LCD_VALUE = data;
    return;
}

unsigned short P16_LCD_read_dat(volatile unsigned short index)
{
    volatile unsigned short data;
    FM3_GPIO->PDOR0_f.P8 = 0;   // RS 0
    LCD_ADDRESS = index;
    FM3_GPIO->PDOR0_f.P8 = 1;   // RS 1
    data = LCD_VALUE;
    return data;
}
#endif
//--//
